﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using iTFF.WPF.Model.lastfm;
using iTFF.WPF.Helpers;
using System.Xml.Linq;
using System.Data.SqlServerCe;
using iTFF.WPF.Model.lastfm.Queries;
using System.Data;
using iTFF.WPF.Resources.Languages;

namespace iTFF.WPF.CP
{
    class LastfmControlPanel
    {
        #region Constants

        static readonly string URL = "http://ws.audioscrobbler.com/2.0/?method={0}&api_key={1}";

        /// <summary>
        /// The number of days after artist info expire
        /// </summary>
        static readonly int EXPIRE_DAYS = 30;

        #endregion

        #region Private helpers

        private string APIKey
        {
            get { return ConfigurationManager.AppSettings["LastfmKey"]; }
        }

        #endregion

        #region Public methods

        /// <summary>
        /// Gets from the database or downloads from internet the artist info
        /// </summary>
        /// <param name="artist"></param>
        /// <returns></returns>
        public lastfmArtistInfo GetArtistInfo(string artist)
        {

            lastfmArtistInfo info;

            // try to get it from the db
            info = GetArtistInfoFromDB(artist);

            if (info != null)
            {
                if ((DateTime.Now - info.DateAdded) < TimeSpan.FromDays(EXPIRE_DAYS))
                    return info;
            }

            // get from the web
            info = DownloadArtistInfo(artist);
            if (info != null)
            {
                // save to DB
                //SaveArtistInfoToDB(artist);
                return null;
            }
            else
                return null;

        }

        #endregion

        #region Private methods

        /// <summary>
        /// Returns Artist Info from lastfm web service (or null if error)
        /// </summary>
        /// <param name="artist"></param>
        /// <returns></returns>
        /// <example>url : http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist=Cher&api_key=b25b959554ed76058ac220b7b2e0a026</example>
        private lastfmArtistInfo DownloadArtistInfo(string artist)
        {
            // construct url
            var url = string.Format(URL + "&artist={2}", "artist.getinfo", APIKey, System.Web.HttpUtility.UrlEncode(artist));

            // download the content
            var result = WebHelper.SubmitRequestAndGetResponse(url, null, false);

            if (result != null)
            {

                // parse the content
                XDocument doc = XDocument.Parse(result);

                var status = doc.Elements().First().Attribute("status").Value;

                // continue only if OK
                if (status == "ok")
                {
                    var artistNode = doc.Elements().First().Element("artist");

                    var artistInfo = new lastfmArtistInfo();

                    artistInfo.Artist = artistNode.Element("name").Value;
                    artistInfo.Url = artistNode.Element("url").Value;

                    if (artistNode.Elements("image").Any() && artistNode.Elements("image").Any(n => n.Attribute("size").Value == "large"))
                        artistInfo.ImageLargeURL = artistNode.Elements("image").FirstOrDefault(n => n.Attribute("size").Value == "large").Value;

                    // don't forget to replace lin breaks
                    if (artistNode.Element("bio") != null && artistNode.Element("bio").Element("content") != null)
                        artistInfo.Biography = artistNode.Element("bio").Element("content").Value.Replace("\n", Environment.NewLine);

                    return artistInfo;
                }
                else
                    return null;

            }
            else
                return null;
        }

        /// <summary>
        /// Tries to get the artist info from the DB
        /// </summary>
        /// <param name="artist"></param>
        /// <returns></returns>
        private lastfmArtistInfo GetArtistInfoFromDB(string artist)
        {

            try
            {

                using (SqlCeConnection conn = new SqlCeConnection(ControlPanel.Instance.SQLCeDatabaseConnectionString))
                {

                    SqlCeCommand cmd = new SqlCeCommand(Queries.GetArtistInfo);
                    cmd.Connection = conn;

                    // Create provider specific parameters
                    cmd.Parameters.Add(new SqlCeParameter("@Artist", SqlDbType.NVarChar, artist.Length) { Value = artist });
                    cmd.Connection.Open();
                    var results = cmd.ExecuteReader();

                    DataTable dt = new DataTable();
                    dt.Load(results);

                    if (dt.Rows.Count > 0)
                    {
                        var row = dt.AsEnumerable().First();

                        var info = new lastfmArtistInfo
                        {
                            Artist = (string)row["Artist"],
                            Biography = (string)row["Bio"],
                            ImageLargeURL = (string)row["ImageLargeURL"],
                            Url = (string)row["URL"],
                            DateAdded = (DateTime)row["DateAdded"]
                        };

                        return info;
                    }
                    else
                    {
                        return null;
                    }
                }
            }
            catch (Exception ex)
            {
                throw new ApplicationException(string.Format(Strings.SQLCeException, ex.Message));
            }

        }

        #endregion
    }
}
